/*
*  Copyright 2019-2023 CY
*
*  Licensed under the Apache License, Version 2.0 (the "License");
*  you may not use this file except in compliance with the License.
*  You may obtain a copy of the License at
*
*  http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
*/
package me.zhengjie.modules.ejweixin.service.impl;

import me.zhengjie.modules.ejweixin.domain.NgDistrict;
import me.zhengjie.utils.FileUtil;
import lombok.RequiredArgsConstructor;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import me.zhengjie.modules.ejweixin.service.NgDistrictService;
import me.zhengjie.modules.ejweixin.domain.vo.NgDistrictQueryCriteria;
import me.zhengjie.modules.ejweixin.mapper.NgDistrictMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import me.zhengjie.utils.PageUtil;

import java.util.*;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;

import me.zhengjie.utils.PageResult;

/**
* @description 服务实现
* @author cy
* @date 2025-05-17
**/
@Service
@RequiredArgsConstructor
public class NgDistrictServiceImpl extends ServiceImpl<NgDistrictMapper, NgDistrict> implements NgDistrictService {

    private final NgDistrictMapper ngDistrictMapper;

    @Override
    public PageResult<NgDistrict> queryAll(NgDistrictQueryCriteria criteria, Page<Object> page){
        return PageUtil.toPage(ngDistrictMapper.findAll(criteria, page));
    }

    @Override
    public List<NgDistrict> queryAll(NgDistrictQueryCriteria criteria){
        return ngDistrictMapper.findAll(criteria);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void create(NgDistrict resources) {
        // 点击左上角的新增时候 默认是第一级省会
        if(null == resources.getFId()){
            resources.setLv("1");
        }else{
            String fLv = resources.getLv();
            Integer intLv = Integer.parseInt(fLv);
            intLv ++;
            resources.setLv(intLv.toString());
        }
        save(resources);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(NgDistrict resources) {
        NgDistrict ngDistrict = getById(resources.getId());
        ngDistrict.copy(resources);
        saveOrUpdate(ngDistrict);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteAll(List<Integer> ids) {
        List<NgDistrict> districtList = ngDistrictMapper.findAll(new NgDistrictQueryCriteria());
        List delList = new ArrayList<Integer>();
        for(Integer id:ids){
            delList.add(id);
            for(NgDistrict district:districtList){
                if(null != district.getFId() && district.getFId().equals(id)){
                    delList.add(district.getId());
                    delList.addAll(getDel(district.getId(), districtList));
                }

            }
        }
        removeBatchByIds(delList);
    }

    private List<Integer> getDel(Integer id, List<NgDistrict> districtList){
        List delList = new ArrayList<Integer>();
        for(NgDistrict district:districtList){
            if(null != district.getFId() && district.getFId().equals(id)){
                delList.add(district.getId());
                delList.addAll(getDel(district.getId(), districtList));
            }
        }
        return delList;
    }

    @Override
    public void download(List<NgDistrict> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (NgDistrict ngDistrict : all) {
            Map<String,Object> map = new LinkedHashMap<>();
            map.put(" lv",  ngDistrict.getLv());
            map.put(" districtName",  ngDistrict.getDistrictName());
            map.put(" fId",  ngDistrict.getFId());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }

    @Override
    public List<Map<String, Object>> getDistrict() {
        List<NgDistrict> districtList = ngDistrictMapper.findAll(new NgDistrictQueryCriteria());
        List resData = new ArrayList<Map<String, Object>>();
        for(NgDistrict list:districtList){
            if(list.getLv().equals("1")){
                Map s = new HashMap<String, Object>();
                s.put("name", list.getDistrictName());
                List<Map<String, Object>> q = getDistrictQ(list.getId(), districtList);
                s.put("cities", q);
                resData.add(s);
            }
        }
        return resData;
    }

    @Override
    public List<Map<String, Object>> getDistrictBack() {
        List<NgDistrict> districtList = ngDistrictMapper.findAll(new NgDistrictQueryCriteria());
        List res = new ArrayList<Map<String, Object>>();
        for(NgDistrict d:districtList){
            if(null == d.getFId() || d.getFId().equals("")){
                Map dto = new HashMap<String, Object>();
                dto.put("id", d.getId());
                dto.put("label", d.getDistrictName());
                dto.put("pid", d.getFId());
                dto.put("lv", d.getLv());
                dto.put("districtName", d.getDistrictName());

                List children = dg(d.getId(), districtList);
                if(null != children && !children.isEmpty()){
                    dto.put("children", children);
                }else{
                    dto.put("children", new ArrayList<>());
                }
                res.add(dto);
            }
        }
        return res;
    }

    private static List<Map<String, Object>> dg(Integer fId, List<NgDistrict> districtList){
        List res = new ArrayList<Map<String, Object>>();
        for(NgDistrict d:districtList){
            if(fId.equals(d.getFId())){
                Map dto = new HashMap<String, Object>();
                dto.put("id", d.getId());
                dto.put("label", d.getDistrictName());
                dto.put("pid", d.getFId());
                dto.put("lv", d.getLv());
                dto.put("districtName", d.getDistrictName());
                List children = dg(d.getId(), districtList);
                if(null != children && !children.isEmpty()){
                    dto.put("children", children);
                }else{
                    dto.put("children", new ArrayList<>());
                }
                res.add(dto);
            }
        }
        return res;
    }


    private List<Map<String, Object>> getDistrictQ(int id, List<NgDistrict> districtList){
        List resData = new ArrayList<Map<String, Object>>();
        for(NgDistrict list:districtList){
            if(null != list.getFId() && list.getLv().equals("2") && list.getFId().equals(id)){
                Map s = new HashMap<String, Object>();
                s.put("name", list.getDistrictName());
                List<String> x = getDistrictX(list.getId(), districtList);
                s.put("districts", x);
                resData.add(s);
            }
        }
        return resData;
    }

    private List<String> getDistrictX(int id, List<NgDistrict> districtList){
        List resData = new ArrayList<String>();
        for(NgDistrict list:districtList){
            if(null != list.getFId() && list.getLv().equals("3") && list.getFId().equals(id)){
                resData.add(list.getDistrictName());
            }
        }
        return resData;
    }
}